package es.udc.acs.consorcio.mensaje;

import java.io.ObjectInputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Vector;

import es.udc.acs.consorcio.client.DataClient;
import es.udc.acs.consorcio.sesion.GestorSesion;
import es.udc.acs.consorcio.sesion.Sesion;
import es.udc.acs.database.Database;
import es.udc.acs.database.operations.DBConsorcioOperations;
import es.udc.acs.parser.ParserMensaje;
import es.udc.acs.utils.CodigosFAP;
import es.udc.acs.utils.GestorProperties;


public class GestorMensaje {

	private static volatile Vector<Mensaje> mensajes = new Vector<Mensaje>();
	
	private GestorMensaje(){}
	
	
	public static boolean addMensaje(Mensaje mensaje) {
		
		try {
			
			// primero vemos que la cantidad de la tarjeta no supere 1000
			if (DBConsorcioOperations.
					comprobarImporteTarjeta(mensaje.getIdbanco(), 
					                        mensaje.getIdtarjeta(), 
					                        mensaje.getImporte())) {	
				
				int idMensaje =  DBConsorcioOperations.
				                crearMensajeConsorcio(mensaje.getIdbanco(), 
										              mensaje.getIdtarjeta(),
										              mensaje, 
										              mensaje.getImporte(), 
										              mensaje.getEstado());

				mensaje.setIdMensaje(idMensaje);
				mensajes.add(mensaje);
				
				return true;
			} else {
				return false;
			}
			
		} catch (Exception e) {
			System.out.println("El mensaje no se ha guardado");
			return false;
		}
	}
	
	
	/**
	 * Recupera los mensajes de la base de datos
	 */
	public static void cargarMensajes() {
		
		Connection conexion = Database.getInstancia().getConexion();

		try {
		    String sentencia = "SELECT obj_mensaje " 
		    		            +"FROM c_mensaje ";

 
			Statement stmt = conexion.createStatement();
		    ResultSet rs   = stmt.executeQuery(sentencia);	  
			
			while (rs.next()) {
				
				Blob blob = rs.getBlob(1);

			   // Se reconstruye el objeto con un ObjectInputStream
			   ObjectInputStream ois = new ObjectInputStream(blob.getBinaryStream());
			   Mensaje mensaje = (Mensaje) ois.readObject();
	        		
			   mensajes.add(mensaje);
	        }	
		} catch (Exception e) {
			System.out.println("Error al recuperar mensajes/No hay");
		}
		
	}


	public static void enviarMensajes(String idBanco) {
		
		Sesion sesion = GestorSesion.getSesion(idBanco);
		String pregunta;
		String codPregunta;
		String cuerpo;
		String subcabecera;
		String message;
		String response;
		
		if((sesion == null) || sesion.obtenerEstado().equals("Trafico detenido")){
			return;
		}
		
		
		for (Mensaje m : mensajes) {
			// mandamos los mensajes offline del banco
			if (m.getIdbanco().equals(idBanco) 
					&& m.getEstado() == 0) {
				
				pregunta    = m.getMensaje();
				codPregunta = ParserMensaje.obtenerTipo(pregunta);
				cuerpo      = ParserMensaje.obtenerCuerpo(pregunta);
	
				//Pedir permiso a sesion para ejecutar la pregunta y que nos devuelva
				//el canal
				subcabecera = sesion.sendMessage(GestorProperties.devolverPropiedad(GestorProperties.IDCONSORCIO) 
                                                 + sesion.getBanco() 
                                                 + codPregunta + "0" 
                                                 + cuerpo);
				
				if(subcabecera.length() == 2){
					continue;
				}
				
				//Formar pregunta y mandarla al cliente del Banco.
				message = GestorProperties.devolverPropiedad(GestorProperties.IDCONSORCIO) 
						  + idBanco + codPregunta + subcabecera + "0" 
						  + cuerpo;
				response = DataClient.sendMessage(message, sesion);
						
				// response es correcta
				if (response != null) {
					m.setEstado(1);
					aumentarMarcadores(sesion,response,codPregunta);
					
					try {
						DBConsorcioOperations.
							actualizarMensajeConsorcio(idBanco, 
								                       m.getIdtarjeta(),
								                       m.getIdMensaje(),
						                               m);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
 			
		}
		
	}
	
	private static void aumentarMarcadores(Sesion sesion,String res,String tipo) {
		try {
			// para llevar la cuenta del numero de operaciones
			if (res.substring(0, 2).equals(CodigosFAP.CR_CONSULTA_ACEPTADA)) {
				
				if (tipo.equals(CodigosFAP.CM_C_PD_REINTEGRO)) {
					sesion.sumarReintegro();
				} else if (tipo.equals(CodigosFAP.CM_C_PD_ABONO)) {					
					sesion.sumarAbono();
				} else if (tipo.equals(CodigosFAP.CM_C_PD_TRASPASO)) {
					sesion.sumarTraspaso();		
				}
			}	
		} catch(Exception e) {}
	}
}
